// menu.c

#define _FWMENU_
//#define CHUKWUWETA 1
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>

#include "rad.h"
#include "smack.h"
#include "dosext.h"
#include "svga.h"
#include "menu.h"
#include "sprite.h"
#include "player.h"
#include "event.h"
#include "xenon.h"
#include "keyboard.h"
#include "secrtimr.h"
#include "sgdef.h"
#include "sound.h"
#include "debug.h"

extern Smack *smk;
extern char g_pauseon;
extern long g_curframe;
extern long g_nextscenenumber;
extern long g_currentscenenumber;
extern long g_nummenus;
extern char g_incyberspace;


extern int bufferbytexchg(char *,char *,long);
extern int processkeyboard();
extern int bufferbyteyankfromscr(char *,char *,long);

extern int inittoolsweaps();
extern int initplayerinfo();
extern char g_asciimap[];
extern xfont  g_font[];    /* Font data */

//Function definitions
//Ordinary game play menu functions.
long (*ProcessEntry) (char keyentered,char *screenbuf);
long  ProcessMainEntry(char keyentered,char *screenbuf);
long  ProcessSaveEntry(char keyentered,char *screenbuf);
long  ProcessLoadEntry(char keyentered,char *screenbuf);
long  ProcessOptsEntry(char keyentered,char *screenbuf);
long  ProcessCtlsEntry(char keyentered,char *screenbuf);
long  ProcessAudiEntry(char keyentered,char *screenbuf);

void  PlaceLoadGameText(long menunum,char *screenbuf);
void  PlaceSaveGameText(long menunum,char *screenbuf);
char  EnterSaveGameText(long menunum,char *screenbuf);

//Secret Room menu functions
long  ProcessSecrRmEntry(char keyentered,char *screenbuf);

long g_presbutton;
unsigned char g_blink   =0;
char          g_blinker =0;
char          secrcode  =0;
char         *g_secrstill = (char *) NULL;

void DisplaySecrRm(char *iimage,char *oimage);

void LoadMenus(long menutype)
{
	long nummenus,mnf,menunum,biggestbutton=0;
	long numbuttons;
	long x,y,b,binfsize,bisize,frsize=0;
	unsigned long rsize;
	char menuname[32],errormsg[64];
	short owidth,oheight,mwidth,mheight,pwidth,pheight;
	MENU *lmenu; //Menu loaded

	if(menutype == GAMEMENUTYPE)
	{
#ifndef CHUKWUWETA 
	if(INCYBERSPACE)
		sprintf(menuname,"%s\\data\\cybmenu.mn",g_cdrom);
	else
		sprintf(menuname,"%s\\data\\relmenu.mn",g_cdrom);
#else
	if(INCYBERSPACE)
		sprintf(menuname,"c:\\data\\cybmenu.mn");
	else
		sprintf(menuname,"c:\\data\\relmenu.mn");
#endif
	}
	else
#ifndef CHUKWUWETA
		sprintf(menuname,"%s\\data\\scrmenu.mn",g_cdrom);
#else
		sprintf(menuname,"c:\\data\\scrmenu.mn");
#endif

	//Read in the unm file
	if((mnf=open(menuname,(O_RDONLY | O_BINARY))) <0)
	{
		sprintf(errormsg,"Couldn't open %s\n",menuname);
		fatalerror(errormsg);
		exit(0);
	}
	
    GetMenuMemory(-1);  //Initialize memory for for the menus

	frsize = read(mnf,&g_nummenus,sizeof(long));

	lmenu = (MENU *) GetMenuMemory((g_nummenus * sizeof(MENU)));
	memset(lmenu,0,(g_nummenus * sizeof(MENU)));

	for(x=0; x < g_nummenus; ++x)
	{
		biggestbutton =0;
		numbuttons = lmenu[x].numbuttons;

		rsize  = sizeof(MENU);
		rsize -= sizeof(MENUB *);
		rsize -= (2 * sizeof(MENUI));

		frsize += read(mnf,(char *) &(lmenu[x]),rsize);

		if(lmenu[x].numbuttons)
		 {
		  lmenu[x].buttons=(MENUB *) GetMenuMemory((lmenu[x].numbuttons * sizeof(MENUB)));
		  memset(lmenu[x].buttons, 0, (lmenu[x].numbuttons * sizeof(MENUB)));
		 }

		//Read buttons;	
		for(b =0; b < lmenu[x].numbuttons; ++b)
		{
			if(x==4)
				x=4;
			binfsize = sizeof(MENUB);
			binfsize -= sizeof(char);
			binfsize -= sizeof(short);
			binfsize -= sizeof(short);
			binfsize -= sizeof(char *);
			frsize+=read(mnf,&lmenu[x].buttons[b],binfsize);
			frsize+=read(mnf,&lmenu[x].buttons[b].hasimage,sizeof(char));

			if(lmenu[x].buttons[b].hasimage)
			{
				owidth  = lmenu[x].buttons[b].bwidth;
				oheight = lmenu[x].buttons[b].bheight;
				frsize+=read(mnf,&lmenu[x].buttons[b].bwidth,sizeof(short));
				frsize+=read(mnf,&lmenu[x].buttons[b].bheight,sizeof(short));
				bisize  = lmenu[x].buttons[b].bwidth;
				bisize *= lmenu[x].buttons[b].bheight;

				if(biggestbutton  < bisize)
					biggestbutton = bisize;

				lmenu[x].buttons[b].bimage = (char *) GetMenuMemory(bisize);
				frsize =read(mnf,lmenu[x].buttons[b].bimage,bisize);
			}
			else
			{
				lmenu[x].buttons[b].bimage = (char *) NULL;
				lmenu[x].buttons[b].bwidth = 0;
				lmenu[x].buttons[b].bheight= 0;
			}
		}

		//Read Main Menu
		rsize = sizeof(MENUI) -  (sizeof(char *) + sizeof(char *));
		mwidth  = lmenu[x].MainImage.width;
		mheight = lmenu[x].MainImage.height;
		frsize+=read(mnf,&(lmenu[x].MainImage),rsize);

		lmenu[x].MainImage.Scratch   = (char *) GetMenuMemory((lmenu[x].MainImage.width * lmenu[x].MainImage.height));
		lmenu[x].MainImage.ImageData = (char *) GetMenuMemory((lmenu[x].MainImage.width * lmenu[x].MainImage.height));

		frsize+=read(mnf,lmenu[x].MainImage.ImageData,(lmenu[x].MainImage.width * lmenu[x].MainImage.height));
    
		//Read Pick Menu
		pwidth  = lmenu[x].PickImage.width;
		pheight = lmenu[x].PickImage.height;
		frsize+=read(mnf,&(lmenu[x].PickImage),rsize);

		lmenu[x].PickImage.ImageData = (char *) GetMenuMemory((lmenu[x].PickImage.width * lmenu[x].PickImage.height));
		lmenu[x].PickImage.Scratch  = (char *) GetMenuMemory((lmenu[x].PickImage.width * lmenu[x].PickImage.height));

		frsize+=read(mnf,lmenu[x].PickImage.ImageData,(lmenu[x].PickImage.width * lmenu[x].PickImage.height));
	}

	close(mnf);

	if (menutype == GAMEMENUTYPE) 
		g_menus     =  lmenu;
	else
		g_secrrmmenu =  lmenu;
}

void AccessMenu(long menunum,char *presscreenbuf,long openclose)
{
long wh;
char *bufstart;
MENU *imenu;
long aliascolor = (menunum == SCRMMENU) ? 255 : 0;

 if(menunum == SCRMMENU)
  imenu =  g_secrrmmenu;
 else
  imenu = &g_menus[menunum];

#if 0
 if((menunum < 0) || (menunum > g_nummenus))
   {
    fatalerror("Error opening a menu\n");
	exit(1);
   }
#endif

  //Place Menu Image
  bufstart =presscreenbuf + (imenu->x);// + g_windowx);
  bufstart+=(PICWIDTH * (imenu->y));// + g_windowy));
  wh = imenu->MainImage.width;
  wh = wh << 16;
  wh += imenu->MainImage.height;

 if(openclose == MENU_OPEN)
 {
  bufferbyteyankfromscr(imenu->MainImage.Scratch,bufstart,wh);
  bufferbytepastewa(bufstart,imenu->MainImage.ImageData,wh,aliascolor);
 }
 else
  bufferbytepaste(bufstart,imenu->MainImage.Scratch,wh);
}

void AccessButton(long menunum,long buttonnum,char *presscreenbuf,long opnclose)
{
long wh;
char *bufstart;
MENU *imenu;
long aliascolor = (menunum == SCRMMENU) ? 255 : 0;

 if(menunum == SCRMMENU)
  imenu =  g_secrrmmenu;
 else
  imenu = &g_menus[menunum];

  //Place Pick
  if((buttonnum < 0) || (buttonnum > imenu->numbuttons))
   {
    fatalerror("MENU : Error in the number of buttons\n");
	exit(1);
   }

  //bufstart =presscreenbuf+imenu->buttons[buttonnum].bx;
  //bufstart+=(PICWIDTH * imenu->buttons[buttonnum].by);
  bufstart =presscreenbuf+(imenu->buttons[buttonnum].bx);// + g_windowx);
  bufstart+=(PICWIDTH * (imenu->buttons[buttonnum].by));// + g_windowy));
  if(imenu->buttons[buttonnum].bimage == NULL)
   {
    wh = imenu->PickImage.width;
    wh = wh << 16;
    wh += imenu->PickImage.height;
   }
   else
   {
    wh = imenu->buttons[buttonnum].bwidth;
    wh = wh << 16;
    wh += imenu->buttons[buttonnum].bheight;
   }

  if(opnclose == MENU_OPEN)
  {
   bufferbyteyankfromscr(imenu->PickImage.Scratch,bufstart,wh);
   if(imenu->buttons[buttonnum].bimage == NULL)
    bufferbytepastewa(bufstart,imenu->PickImage.ImageData,wh,aliascolor);
   else
    bufferbytepastewa(bufstart,imenu->buttons[buttonnum].bimage,wh,aliascolor);
  }
  else
     bufferbytepaste(bufstart,imenu->PickImage.Scratch,wh,0);
}

void ProcessMenu(long menunum,char *screenbuf)
{
long leavemenu =FALSE;

if(menunum == SCRMMENU)
  g_presbutton = g_secrrmmenu->initialbutton;
else if(menunum == AUDIMENU)
  g_presbutton = (g_soundvol / SOUND_INC);
else
  g_presbutton = g_menus[menunum].initialbutton;

 if(menunum == SCRMMENU)
  {
	g_secrrmtimerini=2;
    FWSecrtimer_InstallDriver(); 
    g_secrstill = malloc(SCREENBUFFERSIZE);
	buffercopylongs(g_secrstill,screenbuf,SCREENBUFFERSIZE);
    DisplaySecrRm(g_secrstill,screenbuf);
 }

  OpenMenu(menunum,screenbuf);
  if((menunum != SCRMMENU) && (g_menus[menunum].numbuttons))
   OpenButton(menunum,g_presbutton,screenbuf);

 switch(menunum)
  {
   case MAINMENU:
    ProcessEntry = *(ProcessMainEntry);
	break;
   case SAVEMENU:
    g_blink = g_blinker =0;
    ProcessEntry = *(ProcessSaveEntry);
	PlaceSaveGameText(menunum,screenbuf);
	break;
   case LOADMENU:
    ProcessEntry = *(ProcessLoadEntry);
	PlaceLoadGameText(menunum,screenbuf);
	break;
   case OPTSMENU:
    ProcessEntry = *(ProcessOptsEntry);
	break;
   case CTLSMENU:
    ProcessEntry = *(ProcessCtlsEntry);
	break;
   case AUDIMENU:
	 if (g_gotsound)
      ProcessEntry = *(ProcessAudiEntry);
	 else
	 	leavemenu = TRUE;
	break;

   case SCRMMENU:
   srand(1);

   secrcode     = 0x0A;


   if(secrcode & codes[SRMB_ENTRY4])
   {
    OpenButton(SCRMMENU,SRMB_TRIANGLE,screenbuf);
	g_presbutton = SRMB_ENTRY4;
   }

   if(secrcode & codes[SRMB_ENTRY3])
   {
    OpenButton(SCRMMENU,SRMB_OBLONG,screenbuf);
	g_presbutton = SRMB_ENTRY3;
   }

   if(secrcode & codes[SRMB_ENTRY2])
   {
    OpenButton(SCRMMENU,SRMB_SQUARE,screenbuf);
	g_presbutton = SRMB_ENTRY2;
   } 

   if(secrcode & codes[SRMB_ENTRY1])
   {
    OpenButton(SCRMMENU,SRMB_CIRCLE,screenbuf);
	g_presbutton = SRMB_ENTRY1;
   }

   OpenButton(SCRMMENU,g_presbutton,screenbuf);
   ProcessEntry = *(ProcessSecrRmEntry);
   break;
   default:
     fatalerror("MENU unknown menu. Unable to handle keyboard\n");
  }

    g_keypressed=0; //Reset keyboard
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   

  g_keypressed=0; //Reset keyboard

  while(leavemenu == FALSE)
  {
    if(menunum == SCRMMENU) //ProcessSecrm has its own loop
 	 g_keypressed =1;

    while(!g_keypressed);

    leavemenu = ProcessEntry(g_keypressed,screenbuf);

	g_keypressed=0;
    FWKeyboard_ClearBuffer();
  }

done:
if(g_menus[menunum].numbuttons)
  CloseButton(menunum,g_presbutton,screenbuf);

  CloseMenu(menunum,screenbuf);
  if(g_secrstill)
   {free(g_secrstill); g_secrstill = (char *) NULL;}
}

#define SECRTXTWIDTH  20
#define SECRTXTHEIGHT 20
long ProcessSecrRmEntry(char keyentered,char *screenbuf)
{
 short numenterhit=0;
 long newb = -1;
 long tool,weap,g_savebutton,g_loadinit;
 long  countdown = NUMSECRRMSECS;
 static long lastdown=SRMB_ENTRY1;
 static char  b1func=0,b2func=1,b3func=0,b4func=1;
 char   oldcode = secrcode,message[50];
 char   yankbuf[(SECRTXTWIDTH * SECRTXTHEIGHT)];
 char   *bufferstart,firsthit=0;
 long   wh;

 wh=15;
 wh= wh<<16;
 wh+=15;
 bufferstart=screenbuf + 10 + (PICWIDTH * 10);
 bufferbyteyankfromscr(yankbuf, bufferstart,wh);

 b1func  =  random(30);
 b2func  =  random(31);
 b3func  =  random(32);
 b4func  =  random(33);

 g_textcol    = 0x59; //Red
 g_keypressed     =0;
 g_secrrmtimersec =0;

#if 1

 while(1)
  {
   while((!g_secrrmtimersec) && (!g_keypressed));
#endif

#if 1
   if(g_keypressed)
   {
#endif
	switch(g_keypressed)
	{
     g_secrrmtimersec=1; //Stop the clock
	 case  MAKE_UP:
	       numenterhit =0;
	       newb = g_secrrmmenu->buttons[g_presbutton].up;
		   if(g_presbutton == SRMB_AIRES)
		    newb=lastdown;
		   lastdown=g_presbutton;
           break;

	 case  MAKE_DOWN: 
	       numenterhit =0;
	       newb = g_secrrmmenu->buttons[g_presbutton].down;
		   if(g_presbutton == SRMB_AIRES)
		    newb=lastdown;
		   lastdown=g_presbutton;
           break;

	 case  MAKE_LEFT: 
	       numenterhit =0;
	       newb = (!g_presbutton) ? SRMB_ENTRY3 : g_presbutton -1;
	       while(1)
		    {
			  if((secrcode & codes[newb])) break;
			  if(newb == g_presbutton) break;
	          newb = (!newb) ? SRMB_ENTRY3 : newb-1;
			}
           break;

	 case  MAKE_RIGHT:
	       numenterhit =0;
	       newb = ((g_presbutton + 1) == SRMB_AIRES) ? 0 : g_presbutton+1;
	       while(1)
		    {
			  if((secrcode & codes[newb])) break;
			  if(newb == g_presbutton) break;
	          newb = ((newb + 1) == SRMB_AIRES) ? 0 : newb+1;
			}
           break;

     case  MAKE_ENTER:
	     if(!firsthit)
		   firsthit = g_presbutton;

         if(numenterhit < 4)  //No just pounding on the enter key Eli
		 {
	      switch(g_presbutton)
		   {
             case SRMB_ENTRY1:
			 if(secrcode)
			     secrcode = secrcode << 1;
		     break;

             case SRMB_ENTRY2:
			 if(secrcode)
			  {
			   secrcode =  secrcode << 1;
			   secrcode = secrcode | 0x01;
              }
		     break;

             case SRMB_ENTRY3:
			 if(secrcode)
			  {
			   secrcode =  secrcode >> 1;
			   if(firsthit != SRMB_ENTRY3)
			    secrcode = secrcode | 0x08;
			  }
		     break;

             case SRMB_ENTRY4:
			 if((secrcode) && (firsthit == SRMB_ENTRY3))
			     secrcode = secrcode >> 1;
		     break;

			 case SRMB_AIRES:
			    
			   if(!(secrcode & 0x0F))
			     g_secrroomsolved = TRUE;
               FWSecrtimer_DestallDriver();
		       return((long) TRUE);

			default: g_keypressed = 0;
			         break;
		   }
		  }
		   break;

	 default : g_keypressed =0;
               FWKeyboard_ClearBuffer();
			   continue;
	           break;
	          
	}

   CloseButton(SCRMMENU,g_presbutton,screenbuf);

   if((newb >= 0) && (g_presbutton  != newb))
	g_presbutton = newb;

   if(oldcode != secrcode) //Enter was hit
    {
	 if     (secrcode & codes[SRMB_ENTRY4]) g_presbutton = SRMB_ENTRY4;
	 else if(secrcode & codes[SRMB_ENTRY3]) g_presbutton = SRMB_ENTRY3; 
	 else if(secrcode & codes[SRMB_ENTRY2]) g_presbutton = SRMB_ENTRY2;
	 else if(secrcode & codes[SRMB_ENTRY1]) g_presbutton = SRMB_ENTRY1;
	 else g_presbutton = SRMB_AIRES;
	 oldcode = secrcode;
    }

    buffercopylongs(screenbuf,g_secrstill,SCREENBUFFERSIZE);

   if(secrcode & codes[SRMB_ENTRY4])
    OpenButton(SCRMMENU,SRMB_TRIANGLE,screenbuf);

   if(secrcode & codes[SRMB_ENTRY3])
    OpenButton(SCRMMENU,SRMB_OBLONG,screenbuf);

   if(secrcode & codes[SRMB_ENTRY2])
    OpenButton(SCRMMENU,SRMB_SQUARE,screenbuf);

   if(secrcode & codes[SRMB_ENTRY1])
    OpenButton(SCRMMENU,SRMB_CIRCLE,screenbuf);

    OpenButton(SCRMMENU,g_presbutton,screenbuf);

    sprintf(message,"%d",countdown);
    printx(10,10,message,screenbuf);
    sprintf(message,"%s","AIRES PROTECTION DAEMON ACTIVATED");
//    printx(100,0,message,screenbuf);
    printx(80,0,message,screenbuf);
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
    bufferbytepaste(bufferstart,yankbuf,wh,0);
    FWKeyboard_ClearBuffer();
    g_keypressed     = 0;
    g_secrrmtimersec = 0; //Restart clock

#if 1
  }
#endif

#if 1
   if(g_secrrmtimersec)
    {
	  if(!countdown)
	   {
          FWSecrtimer_DestallDriver();
		  return((long) TRUE);
	   }

	  //buffercopylongs(g_secrstill,screenbuf,SCREENBUFFERSIZE);
      sprintf(message,"%d",countdown);
      printx(10,10,message,screenbuf);
      sprintf(message,"%s","AIRES PROTECTION DAEMON ACTIVATED");
//      printx(100,0,message,screenbuf);
      printx(80,0,message,screenbuf);
      SVGABlit(screenbuf,0,0,320,200,352,0,0);   
      bufferbytepaste(bufferstart,yankbuf,wh,0);
	  --countdown;
      g_secrrmtimersec = 0;
	}
#endif
 }

   FWSecrtimer_DestallDriver();
   return((long) TRUE);
}

long ProcessMainEntry(char keyentered,char *screenbuf)
{
 long newb = -1;
 long tool,weap,g_savebutton,g_loadinit;
	switch(keyentered)
	{
	 case  MAKE_UP:
	       newb = g_menus[MAINMENU].buttons[g_presbutton].up;
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[MAINMENU].buttons[g_presbutton].down;
           break;

	 case  MAKE_SPACE: case MAKE_ESC:
	       g_pauseon = FALSE;
		   return((long) TRUE);

	 case  MAKE_ENTER:
	       switch(g_presbutton)
		    {
			  case MMB_NEWGAME:
			       g_nextscenenumber    = SC_COASTD;
				   inittoolsweaps();
				   loadblts();
				   g_player.lives       = INITIAL_LIVES;
				   LoadStl(g_currentscenenumber,(char *) NULL);
				   g_killscene          = TRUE;
	               g_pauseon            = FALSE;
			       return((long) TRUE);

              case MMB_SAVEGAME:
				   if(!g_gameplaying)
				     return(FALSE);

                   CloseButton(MAINMENU,g_presbutton,screenbuf);
                   CloseMenu(MAINMENU,screenbuf);
				   g_savebutton = g_presbutton;

			       ProcessMenu(SAVEMENU,screenbuf); 

				   g_presbutton = g_menus[MAINMENU].initialbutton;

                   ProcessEntry = *(ProcessMainEntry); //Remember to 
				                                       //reset handler
                   OpenMenu(MAINMENU,screenbuf);
                   OpenButton(MAINMENU,g_presbutton,screenbuf);
                   SVGABlit(screenbuf,0,0,320,200,352,0,0);   
				   return((long) FALSE);

			 case MMB_LOADGAME:
			       //Must have a saved game
			       for(g_loadinit = 0; 
				       g_loadinit < MAX_SAVEDGAMES;
					   ++g_loadinit)
					  {
					   if(strlen(g_savedgamestext[g_loadinit].saveid))
					    {
						 g_menus[LOADMENU].initialbutton = g_loadinit;
					     break;
						}
					  }

				   if(g_loadinit == MAX_SAVEDGAMES)
				     return(FALSE);

                   CloseButton(MAINMENU,g_presbutton,screenbuf);
                   CloseMenu(MAINMENU,screenbuf);
				   g_savebutton = g_presbutton;

			       ProcessMenu(LOADMENU,screenbuf); 

				   g_presbutton = g_menus[MAINMENU].initialbutton;
                   OpenMenu(MAINMENU,screenbuf);
                   OpenButton(MAINMENU,g_presbutton,screenbuf);
                   ProcessEntry = *(ProcessMainEntry); //Remember to 
				                                       //reset handler

                   if(g_killscene == TRUE)
				     {
			           g_pauseon = FALSE;
					   return((long) TRUE);
					 }

                SVGABlit(screenbuf,0,0,320,200,352,0,0);   
			       g_pauseon = TRUE;
			       return((long) FALSE);

			 case MMB_OPTIONS:
                   CloseButton(MAINMENU,g_presbutton,screenbuf);
                   CloseMenu(MAINMENU,screenbuf);
				   g_savebutton = g_presbutton;

			       ProcessMenu(OPTSMENU,screenbuf); 

				   g_presbutton = g_menus[MAINMENU].initialbutton;
                   OpenMenu(MAINMENU,screenbuf);
                   OpenButton(MAINMENU,g_presbutton,screenbuf);
                   ProcessEntry = *(ProcessMainEntry); //Remember to 
				                                       //reset handler

                SVGABlit(screenbuf,0,0,320,200,352,0,0);   
			       g_pauseon = TRUE;
			       return((long) FALSE);

			 case MMB_QUIT:
			       g_pauseon = FALSE;
				   g_leavegame=TRUE;
				   return((long) TRUE);

            default: fatalerror("Illegal button state in MAIN MENU\n");
		  }

	 default : break;
	}

   if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon))
   {
    CloseButton(MAINMENU,g_presbutton,screenbuf);
	g_presbutton = newb;
    OpenButton(MAINMENU,g_presbutton,screenbuf);
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
   }

   return((long) FALSE);
}

long ProcessAudiEntry(char keyentered,char *screenbuf)
{
 long newb =-1;

	switch(keyentered)
	{
	 case  MAKE_UP:
	       newb = g_menus[AUDIMENU].buttons[g_presbutton].up;
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[AUDIMENU].buttons[g_presbutton].down;
           break;

	 case  MAKE_LEFT:
	       newb = g_menus[AUDIMENU].buttons[g_presbutton].left;
           break;

	 case  MAKE_RIGHT:
	       newb = g_menus[AUDIMENU].buttons[g_presbutton].right;
           break;

	       break;

	 case MAKE_ESC: case  MAKE_ENTER:
	 		if (g_gotsound)
			{
			   changeVolume((long) (g_presbutton * SOUND_INC));
			   return((long) TRUE);
			}
			break;

	 default : return((long) FALSE);
	}

	if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon))
	{
		CloseButton(AUDIMENU,g_presbutton,screenbuf);
		g_presbutton = newb;
		OpenButton(AUDIMENU,g_presbutton,screenbuf);
		SVGABlit(screenbuf,0,0,320,200,352,0,0);   
	   changeVolume((long) (g_presbutton * SOUND_INC));
	}
	return((long) FALSE);
}

long ProcessCtlsEntry(char keyentered,char *screenbuf)
{
 long newb =-1;

	switch(keyentered)
	{
#if 0
	 case  MAKE_UP:
	       newb = g_menus[CTLSMENU].buttons[g_presbutton].up;
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[CTLSMENU].buttons[g_presbutton].down;
           break;

	 case  MAKE_ENTER:
	       break;
#endif

	 case  MAKE_SPACE: case MAKE_ESC:
		   return((long) TRUE);

	 default : return((long) FALSE);
	}

   if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon))
   {
    CloseButton(CTLSMENU,g_presbutton,screenbuf);
	g_presbutton = newb;
    OpenButton(CTLSMENU,g_presbutton,screenbuf);
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
   }
   return((long) FALSE);
}

long ProcessLoadEntry(char keyentered,char *screenbuf)
{
 long newb = -1;
 long tool,weap;
	switch(keyentered)
	{
	 case  MAKE_UP:
	       newb = g_menus[LOADMENU].buttons[g_presbutton].up;
           if(!strlen(g_savedgamestext[newb].saveid))
           {
            while(1)
        	 {
  	          newb = (!newb) ? (MAX_SAVEDGAMES -1) : (newb-1);
	          if((newb == g_presbutton)  ||
                 (strlen(g_savedgamestext[newb].saveid)))
	  	          break;
	         }
           }
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[LOADMENU].buttons[g_presbutton].down;
           if(!strlen(g_savedgamestext[newb].saveid))
           {
            while(1)
        	 {
  	          newb = (newb == (MAX_SAVEDGAMES -1)) ? 0 : (newb+1);
	          if((newb == g_presbutton)  ||
                 (strlen(g_savedgamestext[newb].saveid)))
	  	          break;
	         }
           }
           break;

	 case  MAKE_SPACE: case MAKE_ESC:
		   return((long) TRUE);

	 case  MAKE_ENTER:
	       g_restoregame = g_presbutton;
		   g_killscene   = TRUE;
		   return((long) TRUE);

	 default : break;
	}

   if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon) &&
     (strlen(g_savedgamestext[newb].saveid)))
   {
    CloseButton(LOADMENU,g_presbutton,screenbuf);
	 g_presbutton = newb;
    OpenButton(LOADMENU,g_presbutton,screenbuf);
    PlaceLoadGameText(LOADMENU,screenbuf);
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
   }

   return((long) FALSE);
}

long ProcessSaveEntry(char keyentered,char *screenbuf)
{
 long newb = -1;
 long tool,weap;
	switch(keyentered)
	{
	 case  MAKE_UP:
	       newb = g_menus[SAVEMENU].buttons[g_presbutton].up;
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[SAVEMENU].buttons[g_presbutton].down;
           break;

	 case  MAKE_SPACE: case MAKE_ESC:
		   return((long) TRUE);

     case  MAKE_A:
     case  MAKE_B:
     case  MAKE_C:
     case  MAKE_D:
     case  MAKE_E:
     case  MAKE_F:
     case  MAKE_G:
     case  MAKE_H:
     case  MAKE_I:
     case  MAKE_J:
     case  MAKE_K:
     case  MAKE_L:
     case  MAKE_M:
     case  MAKE_N:
     case  MAKE_O:
     case  MAKE_P:
     case  MAKE_Q:
     case  MAKE_R:
     case  MAKE_S:
     case  MAKE_T:
     case  MAKE_U:
     case  MAKE_V:
     case  MAKE_W:
     case  MAKE_X:
     case  MAKE_Y:
     case  MAKE_Z:
	 case  MAKE_ENTER:
	         if(EnterSaveGameText(SAVEMENU,screenbuf))
			  SaveGame(g_presbutton);
			  return((long) TRUE);

	 default : break;
	}

   if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon))
   {
    CloseButton(SAVEMENU,g_presbutton,screenbuf);
	g_presbutton = newb;
    OpenButton(SAVEMENU,g_presbutton,screenbuf);
	PlaceSaveGameText(SAVEMENU,screenbuf);
    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
   }

   return((long) FALSE);
}

long ProcessOptsEntry(char keyentered,char *screenbuf)
{
 long newb = -1,g_savebutton;
 long tool,weap;
   switch(keyentered)
	{
	 case  MAKE_UP:
	       newb = g_menus[OPTSMENU].buttons[g_presbutton].up;
           break;

	 case  MAKE_DOWN: 
	       newb = g_menus[OPTSMENU].buttons[g_presbutton].down;
           break;

	 case  MAKE_SPACE: case MAKE_ESC:
		   return((long) TRUE);

	 case  MAKE_ENTER:
           CloseButton(OPTSMENU,g_presbutton,screenbuf);
           CloseMenu(OPTSMENU,screenbuf);
		   g_savebutton = g_presbutton;

           if(g_presbutton == OMB_ENTRY1)
		    ProcessMenu(CTLSMENU,screenbuf); 
           else
		    ProcessMenu(AUDIMENU,screenbuf); 

		   g_presbutton = g_menus[OPTSMENU].initialbutton;
           OpenMenu(OPTSMENU,screenbuf);
           OpenButton(OPTSMENU,g_presbutton,screenbuf);
           ProcessEntry = *(ProcessOptsEntry); //Remember to 
				                               //reset handler

           g_keypressed =0;
           FWKeyboard_ClearBuffer();
           SVGABlit(screenbuf,0,0,320,200,352,0,0);   
		   return((long) FALSE);

	 default : break;
  }

   if((newb >= 0) && (g_presbutton  != newb) && (g_pauseon))
   {
    	CloseButton(OPTSMENU,g_presbutton,screenbuf);
	    g_presbutton = newb;
   	 OpenButton(OPTSMENU,g_presbutton,screenbuf);
	    SVGABlit(screenbuf,0,0,320,200,352,0,0);   
   }

   return((long) FALSE);
}

void PlaceLoadGameText(long menunum,char *buffer)
{
 long sg=0,c,len,ix,iy,wh,x,y,width,height;
 char *bufferstart,*saveid;

 saveid = (char *) &g_savedgamestext[sg].saveid[0];

  g_textcol = (g_currentscenenumber > SC_GRWALL) ? 215 : 232;
  for(sg =0; sg < MAX_SAVEDGAMES; ++sg)
   {
    if(!(len = strlen(g_savedgamestext[sg].saveid)))
	 continue;
				     ix = (g_menus[menunum].buttons[sg].tx);// + g_windowx);
     iy = (g_menus[menunum].buttons[sg].ty);// + g_windowy);
     printx(ix,iy,g_savedgamestext[sg].saveid,buffer);
  }
}

void PlaceSaveGameText(long menunum,char *buffer)
{
 long sg,c,len,ix,iy,wh,width,height;
 char *bufferstart;

  g_textcol = (g_currentscenenumber > SC_GRWALL) ? 215 : 232;
  for(sg =0; sg < MAX_SAVEDGAMES; ++sg)
   {
    ix      =  g_menus[menunum].buttons[sg].tx;// + g_windowx;
    iy      =  g_menus[menunum].buttons[sg].ty;// + g_windowy;
    if(g_savedgamestext[sg].buffer == (char *) NULL)
	 {
       width  =  SAVEGAMETEXTLENGTH * FWIDTH;
       g_savedgamestext[sg].width =  width;
       height = g_savedgamestext[sg].height =  FHEIGHT;
	   g_savedgamestext[sg].buffer = malloc((width * height));
       wh = width; 
       wh = wh << 16;
       wh += height;
	   bufferstart=buffer + ix + (PICWIDTH * iy);
       bufferbyteyankfromscr(g_savedgamestext[sg].buffer, bufferstart, wh);
	  }  
     if(strlen(g_savedgamestext[sg].saveid))
	   printx(ix,iy,g_savedgamestext[sg].saveid,buffer);
	}
}

char EnterSaveGameText(long menunum,char *screenbuf)
{
long len,ix,iy,wh,width,height,pos=0,lpos;
char *bufferstart,oldtextcol;
char oldtext[SAVEGAMETEXTLENGTH];

oldtextcol = g_textcol;
g_textcol = (g_currentscenenumber > SC_GRWALL) ? 204 : 202;

memcpy(g_lastname,g_savedgamestext[g_presbutton].saveid,SAVEGAMETEXTLENGTH);
memset(g_savedgamestext[g_presbutton].saveid,0,SAVEGAMETEXTLENGTH);
if(g_keypressed == MAKE_ENTER)
{
  g_savedgamestext[g_presbutton].saveid[0] = '*';
  g_keypressed =0;
  FWKeyboard_ClearBuffer();
}

 pos  = 0;
 lpos = pos;


ix     =  g_menus[menunum].buttons[g_presbutton].tx;// + g_windowx;
iy     =  g_menus[menunum].buttons[g_presbutton].ty;// + g_windowy;
width  =  g_savedgamestext[g_presbutton].width;
height =  g_savedgamestext[g_presbutton].height;
wh     =  width;
wh     =  wh << 16;
wh    +=  height;
bufferstart=screenbuf + ix + (PICWIDTH * iy);
bufferbytepaste(bufferstart, g_savedgamestext[g_presbutton].buffer,wh,0);
if(!g_keypressed)
{
  printx(ix,iy,g_savedgamestext[g_presbutton].saveid,screenbuf);
  SVGABlit(screenbuf,0,0,320,200,352,0,0);   
}

while(1)
 {
   while(!g_keypressed);

   if(g_keypressed)
   {

	switch(g_keypressed)
	{
	 case  MAKE_LEFT: case MAKE_DEL: case MAKE_BKSP:
       if(strlen(g_savedgamestext[g_presbutton].saveid))
	    {
	     //g_savedgames[g_presbutton].saveid[pos--] = 0;
		 if(g_savedgamestext[g_presbutton].saveid[pos])
	      g_savedgamestext[g_presbutton].saveid[pos] = 0;
		 else
	      g_savedgamestext[g_presbutton].saveid[--pos] = 0;
		}
	   break;

      case MAKE_A:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	     g_savedgamestext[g_presbutton].saveid[pos++] = 'A';
		break;
      case MAKE_B:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'B';
		break;
      case MAKE_C:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'C';
		break;
      case MAKE_D:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'D';
		break;
      case MAKE_E:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'E';
		break;
      case MAKE_F:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'F';
		break;
      case MAKE_G:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'G';
		break;
      case MAKE_H:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'H';
		break;
      case MAKE_I:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'I';
		break;
      case MAKE_J:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'J';
		break;
      case MAKE_K:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'K';
		break;
      case MAKE_L:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'L';
		break;
      case MAKE_M:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'M';
		break;
      case MAKE_N:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'N';
		break;
      case MAKE_O:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'O';
		break;
      case MAKE_P:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'P';
		break;
      case MAKE_Q:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'Q';
		break;
      case MAKE_R:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'R';
		break;
      case MAKE_S:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'S';
		break;
      case MAKE_T:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'T';
		break;
      case MAKE_U:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'U';
		break;
      case MAKE_V:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'V';
		break;
      case MAKE_W:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'W';
		break;
      case MAKE_X:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'X';
		break;
      case MAKE_Y:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'Y';
		break;
      case MAKE_Z:
	    if(pos != (SAVEGAMETEXTLENGTH-1))
	    g_savedgamestext[g_presbutton].saveid[pos++] = 'Z';
		break;
	 case  MAKE_ESC: //case MAKE_SPACE:
    memcpy(g_savedgamestext[g_presbutton].saveid,g_lastname,SAVEGAMETEXTLENGTH);
	    return(0);
	    break;

	 case  MAKE_ENTER:
	     if((len = strlen(g_savedgamestext[g_presbutton].saveid)) &&
	        (g_savedgamestext[g_presbutton].saveid[0] != '*'))
		 {
	     g_keypressed=0;
         g_textcol = oldtextcol;
         FWKeyboard_ClearBuffer();
	     return(1);
		 }
		 else if(strlen(g_lastname))
		  {
            memcpy(g_savedgamestext[g_presbutton].saveid,g_lastname,SAVEGAMETEXTLENGTH);
	       g_keypressed=0;
           g_textcol = oldtextcol;
           FWKeyboard_ClearBuffer();
	       return(1);
		  }
		  else
		   break;

      default: break;
	  }

      bufferbytepaste(bufferstart, g_savedgamestext[g_presbutton].buffer,wh,0);
	  printx(ix,iy,g_savedgamestext[g_presbutton].saveid,screenbuf);
      SVGABlit(screenbuf,0,0,320,200,352,0,0);   
	  g_keypressed=0;
      FWKeyboard_ClearBuffer();
	 }
	}

  g_textcol = oldtextcol;
}

void DisplaySecrRm(char *oimage,char *iimage)
{
char omessage[64],message[64],*yankbuf,*bufstart;
long x,s1,s2,wh;
#if 0
long wh,blinkcnt,blinksw=0;
long ix1=0,  iy1=0,	 ixx1=159,iyy1=99, x1,y1,xx1,yy1,
     ix2=319,iy2=0,	 ixx2=160,iyy2=99, x2,y2,xx2,yy2,
	 ix3=0,  iy3=199,ixx3=159,iyy3=100,x3,y3,xx3,yy3,
	 ix4=319,iy4=199,ixx4=160,iyy4=100,x4,y4,xx4,yy4;


  ix1 = (ix1==175) ? ix1 :(ix1+1); iy1 = (iy1==99) ? iy1 :(iy1+1);
  ix2 = (ix2==176) ? ix2 :(ix2-1); iy2 = (iy2==99) ? iy2 :(iy2+1);
  ix3 = (ix3==175) ? ix3 :(ix3+1); iy3 = (iy3==99) ? iy3 :(iy3-1);
  ix4 = (ix4==175) ? ix4 :(ix4-1); iy4 = (iy4==99) ? iy4 :(iy4-1);

 memset(oimage,0,SCREENBUFFERSIZE);

 yankbuf      = (char *) malloc(strlen(message) * FWIDTH * FHEIGHT);
 sprintf(message,"%s","AIRES PROTECTION DAEMON ACTIVATED");
 wh           = (strlen(message) *FWIDTH);
 wh           = wh << 16;
 wh          +=FHEIGHT;
// bufstart     = oimage + 100 + (100 * PICWIDTH);
 bufstart     = oimage + 80 + (100 * PICWIDTH);
 bufferbyteyankfromscr(yankbuf,bufstart,wh);
 printx(100,100,message,oimage);

 while(1)
 {
   if(blinksw)
      bufferbytepaste(bufstart,yankbuf,wh);
   else
      printx(100,100,message,oimage);

  for(y1=iy1,y2=iy2,y3=iy3,y4=iy4,yy1=iyy1,yy2=iyy2,yy3=iyy3,yy4=iyy4;
    y1 >= 0; --y1,--y2,++y3,++y4,--yy1,--yy2,++yy3,++yy4)
  for(x1=ix1,x2=ix2,x3=ix3,x4=ix4,xx1=ixx1,xx2=ixx2,xx3=ixx3,xx4=ixx4;
    x1 >= 0; --x1,++x2,--x3,++x4,--xx1,++xx2,--xx3,++xx4)
   {
     oimage[x1 + (y1 * 352)] = iimage[xx1 + (yy1 * 352)];
     oimage[x2 + (y2 * 352)] = iimage[xx2 + (yy2 * 352)];
     oimage[x3 + (y3 * 352)] = iimage[xx3 + (yy3 * 352)];
     oimage[x4 + (y4 * 352)] = iimage[xx4 + (yy4 * 352)];
   }

  ix1 = (ix1==161) ? ix1 :(ix1+1); iy1 = (iy1==99)  ? iy1 :(iy1+1);
  ix2 = (ix2==159) ? ix2 :(ix2-1); iy2 = (iy2==99)  ? iy2 :(iy2+1);
  ix3 = (ix3==161) ? ix3 :(ix3+1); iy3 = (iy3==100) ? iy3 :(iy3-1);
  ix4 = (ix4==159) ? ix4 :(ix4-1); iy4 = (iy4==100) ? iy4 :(iy4-1);

  if((ix1 == 160) && (iy1 == 99)  && 
     (ix2 == 159) && (iy2 == 99)  &&
     (ix3 == 160) && (iy3 == 100) &&
     (ix4 == 159) && (iy4 == 100))
    break;

  blinkcnt = (blinkcnt +1) % 10;
  if(blinkcnt == 9)
   blinksw = ~blinksw;

  SVGABlit(oimage,0,0,320,200,352,0,0);   

  while(!g_secrrmtimersec); //Wait for signal
  g_secrrmtimersec =0;
 }
#endif 

 g_secrrmtimerini=12;
 g_textcol    = 0x59; //Blue
 memset(omessage,0,64);
 yankbuf      = (char *) malloc(352 * FHEIGHT);
 sprintf(message,"%s","AIRES PROTECTION DAEMON ACTIVATED");
 wh           = 352;
 wh           = wh << 16;
 wh          +=FHEIGHT;
 bufstart     = oimage;
 bufferbyteyankfromscr(yankbuf,bufstart,wh);

s1 = 0;
x  = 0;
while(x < 31)
 {
  if(!(x%4))
   s1 = ~s1;

  if(s1)
//   printx(100,0,message,oimage);
   printx(80,0,message,oimage);
  else
   bufferbytepaste(bufstart,yankbuf,wh);

  SVGABlit(oimage,0,0,320,200,352,0,0);   
  while(!g_secrrmtimersec);
  g_secrrmtimersec=0;
  ++x;
 }

 g_keypressed =0;
 g_secrrmtimerini=18;
 printx(100,0,message,oimage);
}

void *GetMenuMemory(long amtreq)
{
 static void *freemempntr,*retmempntr;
 char *errormsg1 = "Not enough memory for Firewall menus\n";
 char *errormsg2 = "Availible Firewall menu memory exceeded\n";

 if(g_menumemory == (void *) NULL)
    if(!(g_menumemory = (void *) malloc(MENUMEMORYSIZE)))
      fatalerror(errormsg1);

  if(amtreq < 0)
    {
	 retmempntr  = g_menumemory;
	 freemempntr = g_menumemory;
	 return((void *) NULL);
	}

  if(!amtreq)
	return((void *) NULL);

  if(((char *) freemempntr + amtreq) > ((char *) g_menumemory + MENUMEMORYSIZE))
     fatalerror(errormsg2);

  retmempntr = freemempntr;
  (char*) freemempntr+=amtreq;

  return(retmempntr);
}

void *FreeMenuMemory(void)
 {
 if(g_menumemory != (void *) NULL)
   free(g_menumemory);
  g_menumemory=(void *) NULL;
 }
